import { Injectable } from '@nestjs/common';
import { AdminModelService } from 'src/model/admin-model/admin-model.service';
const crypto = require('crypto')
import * as dayjs from 'dayjs'
import { ConfigService } from '@nestjs/config';
import { XjwtService } from 'src/xjwt/xjwt.service';
import { MerchantModelService } from 'src/model/merchant-model/merchant-model.service';
import { RedisService } from 'src/redis/redis.service';
import { LoginDto } from './dto';

@Injectable()
export class LoginService {
    constructor(
        private configService:ConfigService,
        private adminModel:AdminModelService,
        private merchantModel:MerchantModelService,
        private xjwtService:XjwtService,
        private redis:RedisService,
    ) {}

    async login(dto:LoginDto, roleType:RoleType) {
        let res
        if(roleType == 0) {
            res = this.platform(dto, roleType)
        }else {
            res = this.merchant(dto, roleType)
        }

        return res
    }


    async platform(dto:LoginDto, roleType) {
        roleType = 0
        const time = dayjs().unix()
        const admin = await this.adminModel.findOne({account : dto.account}, ['adminId', 'password', 'salt', 'super'])
        if(!admin) return false
        const password = (crypto.createHash('md5').update(dto.password + admin.salt).digest('hex')).toLowerCase()
        if(admin.password != password) return null

        this.adminModel.update({adminId : admin.adminId}, {lastLoginTime : time})
        return {king : admin.super, roleType, ...this.makeToken(admin.adminId, roleType, null, time)}

    }

    async merchant(dto:LoginDto, roleType) {
        const time = dayjs().unix()
        const merchant = await this.merchantModel.findOne({account : dto.account, merchantName : dto.merchant}, ['merchantId', 'password', 'salt', 'parentId'])
        if(!merchant) return false
        const password = (crypto.createHash('md5').update(dto.password + merchant.salt).digest('hex')).toLowerCase()
        if(merchant.password != password) return null

        roleType = merchant.parentId == 0 ? 1 : 2

        this.merchantModel.update({merchantId : merchant.merchantId}, {lastLoginTime : time})

        return {roleType, ...this.makeToken(merchant.merchantId, roleType, null, time)}

    }

    refresh(id:number, roleType:RoleType, token:string) {
        const jwtConfig = this.configService.get('jwt')

        let payload = this.xjwtService.verify(token, {
            secret : jwtConfig.refreshLogin.secret
        })

        console.log(payload)

        if(!payload) return null

        const key = (payload.key + jwtConfig.refreshLogin.scale) / jwtConfig.refreshLogin.scale
        if(key != id) return null

        
        return this.makeToken(id, roleType, jwtConfig)
    }

    makeToken(id:number, type:RoleType, jwtConfig?:any, time?:number) {
        if(!jwtConfig) {
            jwtConfig = this.configService.get('jwt')
        }

        if(!time) {
            time = dayjs().unix()
        }
        
        let payload = {uid : 0, key : id * jwtConfig.login.scale + jwtConfig.login.scale, id : Math.ceil((time - 1030) / 263), time : time}
        payload.uid = payload.id + type + jwtConfig.login.scale

        let accessToken = this.xjwtService.sign(payload, {
            secret : jwtConfig.login.secret,
            expiresIn : jwtConfig.expire
        })

        let refreshToken = this.xjwtService.sign({key : id * jwtConfig.refreshLogin.scale - jwtConfig.refreshLogin.scale, rid : Math.ceil((time - 8030) / 463), time : time}, {
            secret : jwtConfig.refreshLogin.secret,
            expiresIn : jwtConfig.expire
        })



        return {
            accessToken,
            refreshToken,
            expire : jwtConfig.expire
        }

    }
    
}
